import $ from 'jquery';
import Module from './Module';
export default class Clipboard extends Module {

  _init() {
    this.editor = this._module;
    if (this.opts.pasteImage && typeof this.opts.pasteImage !== 'string') {
      this.opts.pasteImage = 'inline';
    }
    return this.editor.body.on('paste',  e => {
      let range;
      if (this.pasting || this._pasteBin) {
        return;
      }
      if (this.editor.triggerHandler(e) === false) {
        return false;
      }
      range = this.editor.selection.deleteRangeContents();
      if (this.editor.body.html()) {
        if (!range.collapsed) {
          range.collapse(true);
        }
      } else {
        this.editor.formatter.format();
        this.editor.selection.setRangeAtStartOf(this.editor.body.find('p:first'));
      }
      if (this._processPasteByClipboardApi(e)) {
        return false;
      }
      this.editor.inputManager.throttledValueChanged.clear();
      this.editor.inputManager.throttledSelectionChanged.clear();
      this.editor.undoManager.throttledPushState.clear();
      this.editor.selection.reset();
      this.editor.undoManager.resetCaretPosition();
      this.pasting = true;
      return this._getPasteContent(pasteContent => {
        this._processPasteContent(pasteContent);
        this._pasteInBlockEl = null;
        this._pastePlainText = null;
        return this.pasting = false;
      });
    });
  }

  _processPasteByClipboardApi(e) {
    let imageFile, pasteItem, ref, uploadOpt;
    if (this.editor.util.browser.edge) return;

    if (e.originalEvent.clipboardData && e.originalEvent.clipboardData.items && e.originalEvent.clipboardData.items.length > 0) {
      pasteItem = e.originalEvent.clipboardData.items[0];
      if (/^image\//.test(pasteItem.type)) {
        imageFile = pasteItem.getAsFile();
        if (!((imageFile != null) && this.opts.pasteImage)) return;
        if (!imageFile.name) imageFile.name = "Clipboard Image.png";
        if (this.editor.triggerHandler('pasting', [imageFile]) === false) return;
        uploadOpt = {};
        uploadOpt[this.opts.pasteImage] = true;
        if ((ref = this.editor.uploader) != null) {
          ref.upload(imageFile, uploadOpt);
        }
        return true;
      }
    }
  }

  _getPasteContent(callback) {
    let state;
    this._pasteBin = $('<div contenteditable="true" />').addClass('simditor-paste-bin').attr('tabIndex', '-1').appendTo(this.editor.el);
    state = {
      html: this.editor.body.html(),
      caret: this.editor.undoManager.caretPosition()
    };
    this._pasteBin.focus();
    return setTimeout(((_this => () => {
      let pasteContent;
      _this.editor.hidePopover();
      _this.editor.body.get(0).innerHTML = state.html;
      _this.editor.undoManager.caretPosition(state.caret);
      _this.editor.body.focus();
      _this.editor.selection.reset();
      _this.editor.selection.range();
      _this._pasteInBlockEl = _this.editor.selection.blockNodes().last();
      _this._pastePlainText = _this.opts.cleanPaste || _this._pasteInBlockEl.is('pre, table');
      if (_this._pastePlainText) {
        pasteContent = _this.editor.formatter.clearHtml(_this._pasteBin.html(), true);
      } else {
        pasteContent = $('<div/>').append(_this._pasteBin.contents());
        pasteContent.find('table colgroup').remove();
        _this.editor.formatter.format(pasteContent);
        _this.editor.formatter.decorate(pasteContent);
        _this.editor.formatter.beautify(pasteContent.children());
        pasteContent = pasteContent.contents();
      }
      _this._pasteBin.remove();
      _this._pasteBin = null;
      return callback(pasteContent);
    }))(this), 0);
  }

  _processPasteContent(pasteContent) {
    let $blockEl, $img, blob, children, insertPosition, lastLine, len3, lines, node, o,ref1, uploadOpt;
    if (this.editor.triggerHandler('pasting', [pasteContent]) === false) return;

    $blockEl = this._pasteInBlockEl;
    if (!pasteContent) return;
    if (this._pastePlainText) {
      if ($blockEl.is('table')) {
        lines = pasteContent.split('\n');
        lastLine = lines.pop();
        lines.forEach((line) => {
          this.editor.selection.insertNode(document.createTextNode(line));
          this.editor.selection.insertNode($('<br/>'));
        });
        this.editor.selection.insertNode(document.createTextNode(lastLine));
      } else {
        pasteContent = $('<div/>').text(pasteContent);
        pasteContent.contents().each((i, node) => this.editor.selection.insertNode($(node)[0]))
      }
    } else if ($blockEl.is(this.editor.body)) {
      pasteContent.forEach((node)=>this.editor.selection.insertNode(node));
    } else if (pasteContent.length < 1) {
      return;
    } else if (pasteContent.length === 1) {
      if (pasteContent.is('p')) {
        children = pasteContent.contents();
        if (children.length === 1 && children.is('img')) {
          $img = children;
          if (/^data:image/.test($img.attr('src'))) {
            if (!this.opts.pasteImage) {
              return;
            }
            blob = this.editor.util.dataURLtoBlob($img.attr("src"));
            blob.name = "Clipboard Image.png";
            uploadOpt = {};
            uploadOpt[this.opts.pasteImage] = true;
            if ((ref1 = this.editor.uploader) != null) {
              ref1.upload(blob, uploadOpt);
            }
            return;
          } else if ($img.is('img[src^="webkit-fake-url://"]')) {
            return;
          }
        }
        for (o = 0, len3 = children.length; o < len3; o++) {
          node = children[o];
          this.editor.selection.insertNode(node);
        }
      } else if ($blockEl.is('p') && this.editor.util.isEmptyNode($blockEl)) {
        $blockEl.replaceWith(pasteContent);
        this.editor.selection.setRangeAtEndOf(pasteContent);
      } else if (pasteContent.is('ul, ol')) {
        if (pasteContent.find('li').length === 1) {
          pasteContent = $('<div/>').text(pasteContent.text());
          pasteContent.contents().forEach((node)=>this.editor.selection.insertNode($(node)[0]));
        } else if ($blockEl.is('li')) {
          $blockEl.parent().after(pasteContent);
          this.editor.selection.setRangeAtEndOf(pasteContent);
        } else {
          $blockEl.after(pasteContent);
          this.editor.selection.setRangeAtEndOf(pasteContent);
        }
      } else {
        $blockEl.after(pasteContent);
        this.editor.selection.setRangeAtEndOf(pasteContent);
      }
    } else {
      if ($blockEl.is('li')) {
        $blockEl = $blockEl.parent();
      }
      if (this.editor.selection.rangeAtStartOf($blockEl)) {
        insertPosition = 'before';
      } else if (this.editor.selection.rangeAtEndOf($blockEl)) {
        insertPosition = 'after';
      } else {
        this.editor.selection.breakBlockEl($blockEl);
        insertPosition = 'before';
      }
      $blockEl[insertPosition](pasteContent);
      this.editor.selection.setRangeAtEndOf(pasteContent.last());
    }
    return this.editor.inputManager.throttledValueChanged();
  }
}

Clipboard.pluginName = 'Clipboard';
Clipboard.prototype.opts = {
  pasteImage: false,
  cleanPaste: false
};